using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.Web;
using System.Text;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

using Liberty.Application.GrantManagement;
using Liberty.Application.Kernel;
using Liberty.Application.ServiceMemberManagement;
using Liberty.Domain.ApplicationManagement;
using Liberty.Domain.GrantManagement;
using Liberty.Domain.Kernel;
using Liberty.Domain.NoteManagement;

using Peradigm.Framework.Persistence;
using Peradigm.Framework.UI.Web;
using Peradigm.Framework.Domain.Parties;


namespace Liberty.UI.GrantManagement.Controls
{
    public partial class GrantEditView : AbstractLibertyControl, IView
    {
        #region Constants
        private const string FIELD_VALUE = "Oid",
            FIELD_TEXT = "Description",
            ON_CLICK_EVENT = "onclick",
            TOGGLE_ALTERNATE_SECTION = "ToggleAlternateSection( '{0}', '{1}', '{2}' );",
           
            MSG_SELECT_GRANT_TYPE = "Select Grant Type",
            MSG_SELECT_PAYMENT_METHOD = "Select Payment",
            MSG_SELECT_RELATIONSHIP_TYPE = "Select Relationship Type",
            MSG_SELECT_DELIVERY_METHOD = "Select Delivery",
            MSG_TEXT = "Add a note regarding the recipient...",
            DEFAULT_ITEM = "Select a state";
        private const long RELATIONSHIP_SELF_OID = 1;
            

        #endregion

        #region Event Handlers
        protected void Page_Init( object sender, EventArgs e )
        {
            this.BindDropDownControls();
        }

        protected void Page_Load( object sender, EventArgs e )
        {
            ReferenceValue state = null;
            
            this.ToggleAlternate(this.chkDeliverToAlternateApplicant.ClientID);            

            if (!Page.IsPostBack)
            {
                this.BindList(this.ddlState,
                     this.AddressController.AllStates(), state);

                this.BindList(this.ddlCustodianState,
                     this.AddressController.AllStates(), state);
            }
            List<Note> notes = this.NotesFor( this.Grant );
            this.ucNoteListView.Model = notes;
            this.ucNewNoteView.NoteAddedListeners += new NoteAdded( this.OnNoteAdded );
        }

        private void RegisterControlScripts()
        {
            string toggleScript = String.Format(TOGGLE_ALTERNATE_SECTION, this.chkDeliverToAlternateApplicant.ClientID,
                                                    this.phAlternateSection.ClientID,
                                                    this.ddlCustodianState.ClientID);
                                                   
            this.chkDeliverToAlternateApplicant.Attributes[ON_CLICK_EVENT] = toggleScript;        
        }
                

        protected void ddlRelationshipTypes_SelectedIndexChanged( object sender, EventArgs e )
        {
            Applicant applicant = ( this.IsSelfApplicant() ) ? this.Grant.Case.ServiceMember : null;
            this.PopulateApplicationInfo( applicant );
        }
        
        public override void UpdateView()
        {
            if ( this.IsAsynchPostback )
                return;

            Grant grant = this.Grant;

            if( this.Grant.HasBeenSaved() )
                this.lblGrantNumber.Text = grant.Oid.ToString();

            if ( grant.Type != null )
            {
                this.ddlGrantType.SelectedValue = grant.Type.Oid.ToString();
            }
            this.txtAmount.Text = grant.Value.ToString();

            this.txtCheckNumber.Text = grant.CheckNumber.ToString();
            this.txtNameOnCreditCard.Text = grant.NameOnCreditCard;

            if ( grant.PaymentType != null )
            {
                this.ddlPaymentMethod.SelectedValue = grant.PaymentType.Oid.ToString();
            }
            if ( grant.DeliveryMethod != null )
            {
                this.ddlDeliveryMethod.SelectedValue = grant.DeliveryMethod.Oid.ToString();
            }
 
            if( grant.Applicant != null )
            //this.txtDateApplicationReceived.Text = grant.ApprovalDate1.ToString();  //????
            if ( grant.Applicant.Relationships.Count > 0 )
            {
                this.ddlRelationshipTypes.SelectedValue = ( (Relationship)grant.Applicant.Relationships[0] ).Type.Oid.ToString();
            }
            this.PopulateApplicationInfo( this.Grant.Applicant );

            this.txtDateApplicationReceived.Attributes.Add( "onchange", "formattedDate('" + this.txtDateApplicationReceived.ClientID + "');" );

            //this.txtNote.Text = grant.Notes??

            if (!this.chkDeliverToAlternateApplicant.Checked)
            {
                this.txtCustodianFirstName.Text = string.Empty;
                this.txtCustodianLastName.Text = string.Empty;

                this.txtCustodianAddressLine1.Text = string.Empty;
                this.txtCustodianAddressLine2.Text = string.Empty;
                this.txtCustodianCity.Text = string.Empty;
                this.txtCustodianZip.Text = string.Empty;
                this.ddlCustodianState.SelectedIndex = 0 ;
            }

            if( grant.Custodian != null )
            {
                this.chkDeliverToAlternateApplicant.Checked = true;
                this.txtCustodianFirstName.Text = grant.Custodian.Name;
                this.txtCustodianLastName.Text = grant.Custodian.LastName;

                this.txtCustodianAddressLine1.Text = grant.CustodiansAddress.DeliveryAddress;
                this.txtCustodianAddressLine2.Text = grant.CustodiansAddress.SecondaryUnit;
                this.txtCustodianCity.Text = grant.CustodiansAddress.City;
                this.txtCustodianZip.Text = grant.CustodiansAddress.ZIP;
                this.ddlCustodianState.SelectedItem.Text = grant.CustodiansAddress.State;
            }

            UserVariable userVariable = new UserVariable();

            this.lblCreatedBy.Text = userVariable.User.CanonicalName;
            this.lblDateCreated.Text = this.Grant.CreatedDate.ToShortDateString();

            this.RegisterControlScripts();
            this.phAlternateSection.Disabled = !this.chkDeliverToAlternateApplicant.Checked;
            this.ddlCustodianState.Enabled = this.chkDeliverToAlternateApplicant.Checked;          
        }

        public override void UpdateModel()
        {
            if( ddlGrantType.SelectedIndex > 0 )
            {
                this.Grant.Type = this.GrantController.GrantTypeWith( ddlGrantType.SelectedIndex );
            }
            this.Grant.Value = Convert.ToDecimal( this.txtAmount.Text );

            if( ddlPaymentMethod.SelectedIndex > 0 )
            {
                this.Grant.PaymentType = this.GrantController.PaymentTypeWith( ddlPaymentMethod.SelectedIndex );
            }

            this.Grant.NameOnCreditCard = txtNameOnCreditCard.Text;

            if( txtCheckNumber.Text != String.Empty )
            {
                this.Grant.CheckNumber = int.Parse( txtCheckNumber.Text );
            }

            if( ddlDeliveryMethod.SelectedIndex > 0 )
            {
                this.Grant.DeliveryMethod = this.GrantController.DeliveryMethodWith( ddlDeliveryMethod.SelectedIndex );
            }

            this.UpdateApplicantInfoToModel();
          
            if( this.Grant.Custodian == null && txtCustodianFirstName.Text != string.Empty )
            {
                this.Grant.Custodian = new Person( txtCustodianFirstName.Text,
                    txtCustodianLastName.Text );

                Liberty.Domain.Kernel.Address custAddress = new Liberty.Domain.Kernel.Address(
                                           txtCustodianAddressLine1.Text,
                                           txtCustodianCity.Text,
                                           this.ddlCustodianState.SelectedIndex > 0 ? this.ddlCustodianState.SelectedItem.Text : String.Empty,
                                           txtCustodianZip.Text );
                Grant.CustodiansAddress = custAddress;
            }

            RelationshipType relationshipType = this.GrantController.RelationshipTypeWith( Convert.ToInt32( ddlRelationshipTypes.SelectedValue ) );
            if ( this.Grant.Applicant.Relationships.Count > 0 )
            {
                this.Grant.Applicant.RemoveRelationship( (Relationship)this.Grant.Applicant.Relationships[0] );
            }
            this.Grant.Applicant.RelateTo( relationshipType, this.Grant.Case.ServiceMember );
            //this.Grant.CustodiansAddress.DeliveryAddress = txtCustodianAddressLine1.Text;

            this.Model = this.Grant;
        }
        #endregion

        #region Methods
        public void SaveModel()
        {
            //throw new NotImplementedException( "Uncomment this code when all the controller and broker stuff has been fixed." );
            this.UpdateModel();
            this.GrantController.SaveGrant( this.Grant );
        }
        
        protected void ToggleAlternate(string id)
        {
            this.txtCustodianFirstName.Attributes.Add("onclick", "AlternateToggle(this, " + id + ")");
            this.txtCustodianLastName.Attributes.Add("onclick", "AlternateToggle(this, " + id + ")");
            this.txtCustodianAddressLine1.Attributes.Add("onclick", "AlternateToggle(this, " + id + ")");
            this.txtCustodianAddressLine2.Attributes.Add("onclick", "AlternateToggle(this, " + id + ")");
            this.txtCustodianCity.Attributes.Add("onclick", "AlternateToggle(this, " + id + ")");
            this.txtCustodianZip.Attributes.Add("onclick", "AlternateToggle(this, " + id + ")");
        }
        #endregion

        #region Properties
        #endregion

        #region Private Methods
        private List<Note> NotesFor( Grant grant )
        {
            ServiceMemberController controller = new ServiceMemberController();
            return controller.NotesFrom( grant.Case.ServiceMember );
        }

        protected void OnNoteAdded( Note note )
        {
            ServiceMemberController controller = new ServiceMemberController();
            controller.SaveNote( this.Grant.Case.ServiceMember, note );
            this.ucNoteListView.Model = this.NotesFor( this.Grant );
        }

        private void UpdateApplicantInfoToModel()
        {
            Applicant applicant = ( long.Parse( this.ddlRelationshipTypes.SelectedValue ) == RELATIONSHIP_SELF_OID ) ? Applicant.ApplicantFrom( this.Grant.Case.ServiceMember ) : this.Grant.Applicant; 
            if ( applicant == null )
            {
                applicant = new Applicant( Applicant.NEW_OID, Applicant.NEW_VERSION,
                    txtApplicantFirstName.Text, txtApplicantLastName.Text );
            }

            applicant.FirstName = this.txtApplicantFirstName.Text;
            applicant.LastName = this.txtApplicantLastName.Text;

            if ( txtPrimaryTelephone.Text.Trim() != String.Empty )
            {
                PhoneNumber primaryPhone = new UnvalidatedPhoneNumber( txtPrimaryTelephone.Text );
                applicant.PrimaryPhoneNumber = primaryPhone;
            }

            if ( txtSecondaryTelephone.Text.Trim() != String.Empty )
            {
                PhoneNumber secondaryPhone = new UnvalidatedPhoneNumber( txtSecondaryTelephone.Text );
                applicant.SecondaryPhoneNumber = secondaryPhone;
            }

            if ( txtEmailAddress.Text.Trim() != String.Empty )
            {
                EMailAddress emailAddress = new UnvalidatedEMailAddress( txtEmailAddress.Text );
                applicant.EmailAddress = emailAddress;
            }

            Liberty.Domain.Kernel.Address applicantAddress = new Liberty.Domain.Kernel.Address(
                                                    txtApplicantAddressLine1.Text,
                                                    txtCity.Text,
                                                    this.ddlState.SelectedIndex > 0 ? this.ddlState.SelectedItem.Text : String.Empty,
                                                    txtZip.Text );

            applicant.Address = applicantAddress;
            this.Grant.Applicant = applicant;
        }

        private bool IsSelfApplicant()
        {
            return ( long.Parse( this.ddlRelationshipTypes.SelectedValue ) == RELATIONSHIP_SELF_OID );
        }

        private void PopulateApplicationInfo( Applicant applicant )
        {
            if ( applicant != null )
            {
                this.txtApplicantFirstName.Text = applicant.FirstName.ToString();
                this.txtApplicantLastName.Text = applicant.LastName.ToString();

                this.txtEmailAddress.Text = applicant.EmailAddress.DisplayString;
                this.txtPrimaryTelephone.Text = applicant.PrimaryPhoneNumber.DisplayString;
                this.txtSecondaryTelephone.Text = applicant.SecondaryPhoneNumber.DisplayString;

                if ( applicant.Address != null )
                {
                    this.txtApplicantAddressLine1.Text = applicant.Address.DeliveryAddress;
                    this.txtApplicantAddressLine2.Text = applicant.Address.SecondaryUnit;
                    this.txtCity.Text = applicant.Address.City;
                    this.ddlState.SelectedItem.Text = applicant.Address.State;
                    this.txtZip.Text = applicant.Address.ZIP;
                }

                bool isSelfApplicant = this.IsSelfApplicant();
                this.txtApplicantFirstName.Enabled = !isSelfApplicant;
                this.txtApplicantLastName.Enabled = !isSelfApplicant;
            }
            else
            {
                this.txtApplicantFirstName.Enabled = true;
                this.txtApplicantLastName.Enabled = true;
                this.txtApplicantFirstName.Text = String.Empty;
                this.txtApplicantLastName.Text = String.Empty;
                this.txtEmailAddress.Text = String.Empty;
                this.txtPrimaryTelephone.Text = String.Empty;
                this.txtSecondaryTelephone.Text = String.Empty;
                this.txtApplicantAddressLine1.Text = String.Empty;
                this.txtApplicantAddressLine2.Text = String.Empty;
                this.txtCity.Text = String.Empty;
                this.ddlState.SelectedIndex = 0;
                this.txtZip.Text = String.Empty;
            }
        }

        private void BindDropDownControls()
        {
            this.BindGrantTypes();
            this.BindPaymentMethods();
            this.BindDeliveryMethods();
            this.BindRelationshipTypes();
        }

        private void BindGrantTypes()
        {
            GrantController grantController = new GrantController();
            this.ddlGrantType.DataSource = grantController.GrantTypes();
            this.ddlGrantType.DataTextField = FIELD_TEXT;
            this.ddlGrantType.DataValueField = FIELD_VALUE;
            this.ddlGrantType.DataBind();

            this.ddlGrantType.Items.Insert( 0, new ListItem( MSG_SELECT_GRANT_TYPE, "0" ) );
        }

        private void BindPaymentMethods()
        {
            GrantController grantController = new GrantController();
            this.ddlPaymentMethod.DataSource = grantController.PaymentTypes();
            this.ddlPaymentMethod.DataTextField = FIELD_TEXT;
            this.ddlPaymentMethod.DataValueField = FIELD_VALUE;
            this.ddlPaymentMethod.DataBind();
            this.ddlPaymentMethod.Items.Insert( 0, new ListItem( MSG_SELECT_PAYMENT_METHOD, "0" ) );
        }

        private void BindRelationshipTypes()
        {
            GrantController grantController = new GrantController();
            this.ddlRelationshipTypes.DataSource = grantController.RelationshipTypes();
            this.ddlRelationshipTypes.DataTextField = FIELD_TEXT;
            this.ddlRelationshipTypes.DataValueField = FIELD_VALUE;
            this.ddlRelationshipTypes.DataBind();

            this.ddlRelationshipTypes.Items.Insert( 0, new ListItem( MSG_SELECT_RELATIONSHIP_TYPE, "0" ) );
        }

        private void BindDeliveryMethods()
        {
            GrantController grantController = new GrantController();
            this.ddlDeliveryMethod.DataSource = grantController.DeliveryMethods();
            this.ddlDeliveryMethod.DataTextField = FIELD_TEXT;
            this.ddlDeliveryMethod.DataValueField = FIELD_VALUE;
            this.ddlDeliveryMethod.DataBind();
            this.ddlDeliveryMethod.Items.Insert( 0, new ListItem( MSG_SELECT_DELIVERY_METHOD, "0" ) );
        }

        private void BindList(DropDownList control, IEnumerable items, ReferenceValue model)
        {
            control.Items.Clear();

            control.DataSource = items;
            control.DataValueField = FIELD_VALUE;
            control.DataTextField = FIELD_TEXT;
            control.DataBind();
            control.Items.Insert(0, new ListItem(DEFAULT_ITEM));

            control.ClearSelection();
            if (model != null)
            {
                ListItem selectableItem = control.Items.FindByValue(model.Oid.ToString());
                if (selectableItem != null)
                {
                    selectableItem.Selected = true;
                }
            }
        }

        #endregion

        #region Private Properties

        private Grant Grant
        {
            get
            {
                return (Grant)this.Model;
            }
            set
            {
                i_Grant = value;
            }
        }

        private GrantController GrantController
        {
            get
            {
                if( i_GrantController == null )
                {
                    i_GrantController = new GrantController();
                }
                return this.i_GrantController;
            }
        }

        private AddressController AddressController
        {
            get
            {
                return this.i_AddressController;
            }
        }
        #endregion

        #region Construction and Finalization
        #endregion

        #region Data Elements
        private Grant i_Grant;
        private GrantController i_GrantController;
        private AddressController i_AddressController = new AddressController();
        #endregion
    
}
        
}

